package com.ruoyi.aitseeyon.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.ruoyi.aitcommon.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.aitcommon.anotation.ServiceLog;
import com.ruoyi.aitcommon.service.IAitEntityInfoService;
import com.ruoyi.aitcommon.service.TransService;
import com.ruoyi.aitcommon.vo.AggMap;
import com.ruoyi.common.constant.HttpStatus;

/**
 * OA接口服务的统一入口
 * @author Administrator
 *
 */
@Service
public class ZYOAService {
	@Autowired
	ZYOARestService restservice;
	@Autowired
	TransService transservice;
	@Autowired
	IAitEntityInfoService infoService;
	@Autowired
	EntityCache entityCache;

	/**
	 * OA无流程表单保存
	 * 
	 * @param datas     需要保存的数据,字段为中文
	 * @param oadb        OA DB
	 * @param context   数据相关参数
	 * @param interParm 接口地址
	 */
	@ServiceLog("OA无流程表单保存")
	public List<String> formSave(List<Map<String, Object>> datas, JSONObject oadb, Map<String, Object> context,
			Map<String, Object> interParm, Map<String, Object> entityInfo) throws Exception {
		ExceptionUtils.checkBlankOrUndefined(oadb, "oadb为空");
		ExceptionUtils.checkBlankOrUndefined(context, "context为空");
		ExceptionUtils.checkBlankOrUndefined(interParm, "interParm为空");
		ExceptionUtils.checkBlankOrUndefined(entityInfo, "entityInfo为空");
		ExceptionUtils.checkBlankOrUndefined(context.get("formname"), "context.formname为空");
		String formname = context.get("formname").toString();
//		OA 底表编码字段名
		ExceptionUtils.checkBlankOrUndefined(context.get("codefield"), "context.codefield为空");
		String codefield = context.get("codefield").toString();
//		OA 底表编码中文名
		ExceptionUtils.checkBlankOrUndefined(context.get("codename"), "context.codename为空");
		String codename = context.get("codename").toString();

		List<String> retlist = new ArrayList<>();
		String ret="";
		// 从缓存过滤重复数据
		List<Map<String, Object>> filterlist = entityCache.filterEntityChange(entityInfo, datas);
		if(filterlist==null||filterlist.size()==0){
			return retlist;
		}

//		processStartOne会强制刷新token,这里也只能再次强刷token
//		this.getToken(interParm);
		final String token = restservice.createToken(interParm, oadb);
		interParm.put("token",token);

		String sqltemp = "select * from %s where %s='%s'";
		for (Map<String, Object> data : filterlist) {
			ExceptionUtils.checkBlankOrUndefined(data.get(codename), "获取字段编码错误!,配置:context.codename,值:" + codename);
			String code = data.get(codename).toString();
			String sql = String.format(sqltemp, formname, codefield, code);
			try {
//				检查数据库中是否存在
				List<Map<String, Object>> qrylist = SQLUtils.execQuery(sql, oadb);
				if (qrylist == null || qrylist.size() == 0) {
					//新增流程
					entityInfo.put("oper", "新增");
					ret = restservice.formImportOne(data, context, interParm, oadb);
				} else {
					//修改流程
					entityInfo.put("oper", "修改");
					final Object id = qrylist.get(0).get("ID");
					ObjUtils.checkBlank(id,"底表更新,获取ID失败!sql:[{}]",sql);
					ret = restservice.formUpdateOne(data,id, context, interParm, oadb);
				}
				infoService.insertAitEntityInfo(entityInfo, data, null);
				retlist.add(ret);
			} catch (Exception ex) {
				infoService.insertAitEntityInfo(entityInfo, data, ex);
				retlist.add(ex.getMessage());
			}
		}
		return retlist;
	}

	/**
	 * OA无流程表单保存
	 * 调用OA新接口
	 * @param datas     需要保存的数据,字段为中文
	 * @param oadb        OA DB
	 * @param context   数据相关参数
	 * @param interParm 接口地址
	 */
	@ServiceLog("OA无流程表单保存")
	public List<String> formSaveEx(List<Map<String, Object>> datas, JSONObject oadb, Map<String, Object> context,
								 Map<String, Object> interParm, Map<String, Object> entityInfo) throws Exception {
		ExceptionUtils.checkBlankOrUndefined(oadb, "oadb为空");
		ExceptionUtils.checkBlankOrUndefined(context, "context为空");
		ExceptionUtils.checkBlankOrUndefined(interParm, "interParm为空");
		ExceptionUtils.checkBlankOrUndefined(entityInfo, "entityInfo为空");
		ExceptionUtils.checkBlankOrUndefined(context.get("formname"), "context.formname为空");
		String formname = context.get("formname").toString();
//		OA 底表编码字段名
		ExceptionUtils.checkBlankOrUndefined(context.get("codefield"), "context.codefield为空");
		String codefield = context.get("codefield").toString();
//		OA 底表编码中文名
		ExceptionUtils.checkBlankOrUndefined(context.get("codename"), "context.codename为空");
		String codename = context.get("codename").toString();

		List<String> retlist = new ArrayList<>();
		String ret="";
		// 从缓存过滤重复数据
		List<Map<String, Object>> filterlist = entityCache.filterEntityChange(entityInfo, datas);
		if(filterlist==null||filterlist.size()==0){
			return retlist;
		}

//		processStartOne会强制刷新token,这里也只能再次强刷token
//		this.getToken(interParm);
		final String token = restservice.createToken(interParm, oadb);
		interParm.put("token", token);

		String sqltemp = "select * from %s where %s='%s'";
		for (Map<String, Object> data : filterlist) {
			ExceptionUtils.checkBlankOrUndefined(data.get(codename), "获取字段编码错误!,配置:context.codename,值:" + codename);
			String code = data.get(codename).toString();
			String sql = String.format(sqltemp, formname, codefield, code);
			try {
//				检查数据库中是否存在
				List<Map<String, Object>> qrylist = SQLUtils.execQuery(sql, oadb);
				if (qrylist == null || qrylist.size() == 0) {
					//新增流程
					entityInfo.put("oper", "新增");
					ret = restservice.formImportOneEx(data, context, interParm, oadb);
				} else {
					//修改流程
					entityInfo.put("oper", "修改");
					final Object id = qrylist.get(0).get("ID");
					ObjUtils.checkBlank(id,"底表更新,获取ID失败!sql:[{}]",sql);
					ret = restservice.formUpdateOneEx(data,id, context, interParm, oadb);
				}
				infoService.insertAitEntityInfo(entityInfo, data, null);
				retlist.add(ret);
			} catch (Exception ex) {
				infoService.insertAitEntityInfo(entityInfo, data, ex);
				retlist.add(ex.getMessage());
			}
		}
		return retlist;
	}

	/**
	 * 接收datas为Map,先转换为AggMap,再调用processStart
	 */
	@ServiceLog("OA流程表单发起")
	public List<String> processStart1(List<Map<String,Object>> datas, JSONObject oadb, Map<String, Object> context,
									 Map<String, Object> interParm, Map<String, Object> entityInfo) throws Exception {
		List<AggMap> aggMaps = ListMapUtils.map2Agg(datas);
		return this.processStart(aggMaps,oadb,context,interParm,entityInfo);
	}

	/**
	 * OA流程表单发起
	 * 增加参数 repeat:是否允许重复推送
	 * @param datas     表单数据,字段为中文
	 * @param oadb        OA数据库连接
	 * @param context   数据相关参数
	 * @param interParm 接口地址
	 */
	@ServiceLog("OA流程表单发起")
	public List<String> processStart(List<AggMap> datas, JSONObject oadb, Map<String, Object> context,
			Map<String, Object> interParm, Map<String, Object> entityInfo) throws Exception {
		List<AggMap> insertlist = new ArrayList<AggMap>();
		
		ExceptionUtils.checkBlankOrUndefined(oadb, "oadb为空");
		ExceptionUtils.checkBlankOrUndefined(context, "context为空");
		ExceptionUtils.checkBlankOrUndefined(interParm, "interParm为空");
		ExceptionUtils.checkBlankOrUndefined(entityInfo, "entityInfo为空");
		
		String maintable = context.get("maintable").toString();
		String sontable = context.get("sontable") == null ? null : context.get("sontable").toString();
		String entityname = context.get("entityname").toString();
//		OA 编码字段名
		String codefield = context.get("codefield").toString();
//		OA 编码中文名
		String codename = context.get("codename").toString();
//		允许重复推单
		String repeat="false";
		if(context.containsKey("repeat"))
			repeat=context.get("repeat").toString();

		// 从缓存过滤重复数据
		List<Map<String, Object>> filterlist = entityCache.filterEntityChange(entityInfo, ListMapUtils.agg2Map(datas));

		String sqltemp = "select * from %s where %s='%s'";
		for (Map<String, Object> data : filterlist) {
			String sql = "";
			AggMap agg = new AggMap(data);
			if (agg.getHeadVO().get(codename) == null)
				throw new Exception("获取编码字段错误!,配置:context.codename,值:" + codename);
			String code = agg.getHeadVO().get(codename).toString();
			sql = String.format(sqltemp, maintable, codefield, code);
//			查询OA流程数据
			List<Map<String, Object>> qrylist = SQLUtils.execQuery(sql, oadb);
			if (qrylist == null || qrylist.size() == 0) {
				// 新增流程
				insertlist.add(agg);
			} else {
				// 修改流程
				if(repeat.equals("true")) {
//					这里重复推送,新增特新
					insertlist.add(agg);
				}else {
//					这里不允许重复推送
					String err = "错误:编码[%s]已经存在,且不允许重复推送!";
					err = String.format(err, code);
					LogUtils.error(err);
					entityInfo.put("oper", "新增");
//					infoService.insertAitEntityInfo(entityInfo, agg.toMap(), err);
//					记录错误日志,但是要同步缓存
					infoService.insertAitEntityInfo(entityInfo,agg,null,null,HttpStatus.ERROR_Repeat,err);
				}
			}
		}
		List<String> retlist = new ArrayList<>();
		if (insertlist.size() > 0) {
			retlist = restservice.processStart(insertlist, entityname, interParm, maintable, sontable, entityInfo, context, oadb);
		}

		return retlist;
	}
}
